#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "example.grpc.pb.h"

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using example::Greeter;
using example::HelloRequest;
using example::HelloReply;

#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "data_collection.grpc.pb.h"

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using datacollection::DataCollector;
using datacollection::DataRequest;
using datacollection::DataResponse;

using datacollection::DataKeysRequest;
using datacollection::DataKeysResponse;

class GreeterClient {
public:
    GreeterClient(std::shared_ptr<Channel> channel) : stub_(Greeter::NewStub(channel)), stub_DataCollector_(DataCollector::NewStub(channel))  {}

    std::string SayHello(const std::string& user) {
        HelloRequest request;
        request.set_name(user);

        HelloReply reply;
        ClientContext context;

        Status status = stub_->SayHello(&context, request, &reply);
        if (status.ok()) {
            return reply.message();
        }
        else {
            std::cout << "RPC failed" << std::endl;
            return "RPC failed";
        }
    }
    std::string CollectData(const std::string& sensor_id, double temperature, double humidity, int64_t timestamp) {
        DataRequest request;
        request.set_sensor_id(sensor_id);
        request.set_temperature(temperature);
        request.set_humidity(humidity);
        request.set_timestamp(timestamp);

        DataResponse response;
        ClientContext context;

        Status status = stub_DataCollector_->CollectData(&context, request, &response);
        if (status.ok()) {
            return response.status();
        }
        else {
            std::cout << "RPC failed" << std::endl;
            return "RPC failed";
        }
    }
    std::string CollectKeysData(const std::string& key_id,const std::string keys) {
        DataKeysRequest request;
        request.set_keys_id(key_id);
        request.set_keys(keys);

        DataKeysResponse response;
        ClientContext context;
        Status status = stub_DataCollector_->CollectKeysData(&context, request, &response);
        if (status.ok()) {
            return response.status();
        }
        else {
            std::cout << "RPC failed" << std::endl;
            return "RPC failed";
        }
    }

private:
    std::unique_ptr<Greeter::Stub> stub_;
    std::unique_ptr<DataCollector::Stub> stub_DataCollector_;
};

int main(int argc, char** argv) {
    GreeterClient greeter(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
    std::string user("world");
    std::string reply = greeter.SayHello(user);
    std::cout << "Greeter received: " << reply << std::endl;

    std::string sensor_id = "sensor_1";
    double temperature = 23.5;
    double humidity = 45.0;
    int64_t timestamp = 1627849923;

    std::string response = greeter.CollectData(sensor_id, temperature, humidity, timestamp);
    std::cout << "CollectData Response: " << response << std::endl;


    std::string response2 = greeter.CollectKeysData("SDSDWEW","KEYS_111");
    std::cout << "CollectKeysData Response: " << response2 << std::endl;

    return 0;
}
